package k2_oop.p2_inheritAndPolymorphic.demo03;


/**
 * 多态的执行方式
 *     父类中有的方法，子类也有此方法(重写)，执行子类方法
 *     父类有的方法，子类没有此方法，执行父类方法
 *     父类没有的方法，子类中添加新的方法，无法直接调用
 *
 * 编译时类型和运行时类型
 *     编译时类型：在没有运行之前的编译阶段，有数据类型声明出来的类型
 *               Animal dog = new Dog();编译时类型是 Animal 类型
 *     运行时类型：代码在真正运行的时候才能确定下来的类型
 *               Animal dog = new Dog();运行时类型是 Dog 类型
 */
public class TestDemo3 {

    /**
     * 父类中有的方法，每个子类都进行了重写，就是父类的这个方法的不同表现形式，符合多态的情况
     * 所以这里调用父类的方法，但是因为多态，可以执行实际传递进来的子类对象的方法
     * @param animal
     */
    public void testSpeak(Animal animal){
        animal.speak();
    }

    /**
     * 这里的所有子类的扩展方法在父类中没有定义，所以不符合多态
     * 如果想要调用这些方法的话，需要判断是哪个具体子类的对象后进行强制转换成这个类型的对象，才能进行调用
     * @param animal
     */
    public void testOther(Animal animal){
        //如果animal这个对象此时是Dog类的实例化对象
        if(animal instanceof Dog){
            //把此对象强制转成Dog类的对象
            Dog dog = (Dog) animal;
            dog.protectHouse();
        }else if(animal instanceof Cat){
            Cat cat = (Cat) animal;
            cat.catchMouse();
        } else if (animal instanceof Bird) {
            Bird bird = (Bird) animal;
            bird.eat();
        }
    }


    public static void main(String[] args) {

        TestDemo3 demo = new TestDemo3();

        Animal dog = new Dog();
        Animal cat = new Cat();
        Animal bird = new Bird();

        ((Dog)dog).protectHouse();
        cat.speak();
        bird.speak();
        dog.speak();

//        demo.testSpeak(dog);
//        demo.testSpeak(cat);
//        demo.testSpeak(bird);

//        demo.testOther(dog);
//        demo.testOther(cat);
//        demo.testOther(bird);

    }

}
